home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / Misc / Firewall / Firewall.cpp next >
Encoding:
C/C++ Source or Header  |  2004-09-28  |  19.4 KB  |  652 lines

  1. //--------------------------------------------------------------------------------------
  2. // File: Firewall.cpp
  3. //
  4. // Demonstrate the use of the XP/SP2 firewall API
  5. // It requires the latest Microsoft Platform SDK to compile because it uses the Firewall
  6. // API introduced with Windows XP SP2.
  7. //
  8. // Copyright (c) 2003-2004 Microsoft Corporation. All rights reserved
  9. //--------------------------------------------------------------------------------------
  10.  
  11. #define _WIN32_DCOM
  12. #include <windows.h>
  13. #include <crtdbg.h>
  14. #include <netfw.h>
  15. #include <stdio.h>
  16. #include <conio.h>
  17.  
  18.  
  19.  
  20.  
  21. class FirewallWrapper 
  22. {
  23.         INetFwProfile*  m_pFwProfile;
  24.         HRESULT         m_hrComInit;
  25.  
  26.         HRESULT InitFirewallProfile();
  27.         FirewallWrapper();
  28.     
  29.     public:
  30.  
  31.         static FirewallWrapper* Create();
  32.         ~FirewallWrapper();
  33.  
  34.         BOOL    FirewallPresent() 
  35.             { return m_pFwProfile != NULL; } 
  36.  
  37.         BOOL    IsFirewallActive();
  38.         HRESULT AddAuthorizedApp(
  39.             IN const wchar_t* szFwProcessImageFileName,
  40.             IN const wchar_t* szFwFriendlyName
  41.             );
  42.         HRESULT RemoveAuthorizedApp(
  43.             IN const wchar_t* szFwProcessImageFileName
  44.             );
  45.         BOOL IsAppEnabled( 
  46.             IN const wchar_t* szFwProcessImageFileName
  47.             );
  48.         BOOL AreExceptionsAllowed();
  49. };
  50.  
  51.  
  52.         
  53.         
  54. //--------------------------------------------------------------------------------------
  55. // FirewallWrapper()
  56. //      Initialize Com and fetch a firewall profile
  57. //--------------------------------------------------------------------------------------
  58. FirewallWrapper::FirewallWrapper()
  59.     : m_pFwProfile(NULL)
  60. {}
  61.  
  62.  
  63.  
  64.  
  65. //--------------------------------------------------------------------------------------
  66. // ~FirewallWrapper()
  67. //      Release the firewall profile and uninitialize COM
  68. //--------------------------------------------------------------------------------------
  69. FirewallWrapper::~FirewallWrapper()
  70. {
  71.     // Release the firewall profile.
  72.     if( m_pFwProfile != NULL )
  73.     {
  74.         m_pFwProfile->Release();
  75.     }
  76. }
  77.  
  78.  
  79.  
  80.  
  81. //--------------------------------------------------------------------------------------
  82. // FirewallWrapper::Create()
  83. //--------------------------------------------------------------------------------------
  84. FirewallWrapper* FirewallWrapper::Create()
  85. {
  86.     FirewallWrapper* pfw = new FirewallWrapper;
  87.     if( pfw )
  88.     {
  89.         HRESULT hr = pfw->InitFirewallProfile();
  90.         if( !pfw->FirewallPresent() )
  91.         {
  92.             hr;
  93.             // printf( "Failed to initialize firewall profile: 0x%08lx\n", hr );
  94.             delete pfw;
  95.             pfw = NULL;
  96.         }
  97.     }
  98.     return pfw;
  99. }
  100.  
  101.  
  102.  
  103.  
  104. //--------------------------------------------------------------------------------------
  105. // InitFirewallProfile()
  106. //      Access the firewall and policy to retrieve the firewall profile.  
  107. //          Initialize COM  
  108. //          Retrieve the firewall profile
  109. //--------------------------------------------------------------------------------------
  110. HRESULT FirewallWrapper::InitFirewallProfile()
  111. {
  112.     HRESULT         hr = S_OK;
  113.     INetFwMgr*      pFwMgr = NULL;
  114.     INetFwPolicy*   pFwPolicy = NULL;
  115.  
  116.     m_pFwProfile = NULL;
  117.  
  118.     // Create an instance of the firewall settings manager.
  119.     hr = CoCreateInstance(
  120.             __uuidof(NetFwMgr),
  121.             NULL,
  122.             CLSCTX_INPROC_SERVER,
  123.             __uuidof(INetFwMgr),
  124.             (void**)&pFwMgr
  125.             );
  126.     _ASSERT( hr != CO_E_NOTINITIALIZED && "COM has not been initialized" );
  127.     if( FAILED(hr) )
  128.     {
  129.         // printf( "CoCreateInstance failed: 0x%08lx\n", hr );
  130.         goto cleanup;
  131.     }
  132.  
  133.     // Retrieve the local firewall policy.
  134.     hr = pFwMgr->get_LocalPolicy( &pFwPolicy );
  135.     if( FAILED(hr) )
  136.     {
  137.         // printf( "get_LocalPolicy failed: 0x%08lx\n", hr );
  138.         goto cleanup;
  139.     }
  140.  
  141.     // Retrieve the firewall profile currently in effect.
  142.     hr = pFwPolicy->get_CurrentProfile( &m_pFwProfile );
  143.     if( FAILED(hr) )
  144.     {
  145.         // printf( "get_CurrentProfile failed: 0x%08lx\n", hr );
  146.         goto cleanup;
  147.     }
  148.  
  149. cleanup:
  150.  
  151.     // Release the local firewall policy.
  152.     if( pFwPolicy != NULL )
  153.     {
  154.         pFwPolicy->Release();
  155.     }
  156.  
  157.     // Release the firewall settings manager.
  158.     if( pFwMgr != NULL )
  159.     {
  160.         pFwMgr->Release();
  161.     }
  162.  
  163.     return hr;
  164. }
  165.  
  166.  
  167.  
  168.  
  169. //--------------------------------------------------------------------------------------
  170. // IsFirewallActive()
  171. //      Test if the firewall is on, return as a boolean  
  172. //--------------------------------------------------------------------------------------
  173. BOOL FirewallWrapper::IsFirewallActive()
  174. {
  175.     HRESULT         hr = S_OK;
  176.     VARIANT_BOOL    vbFwEnabled;
  177.  
  178.     // Get the current state of the firewall.
  179.     // This requires the latest Microsoft Platform SDK to compile because 
  180.     // it uses the Firewall API introduced with Windows XP SP2.
  181.     hr = m_pFwProfile->get_FirewallEnabled( &vbFwEnabled );  // upgrade Platform SDK if this fails to compile
  182.     if( FAILED(hr) || vbFwEnabled == VARIANT_FALSE )
  183.     {
  184.         return FALSE;
  185.     }
  186.  
  187.     return TRUE;
  188. }
  189.  
  190.  
  191.  
  192.  
  193. //--------------------------------------------------------------------------------------
  194. // FirewallWrapper::IsAppEnabled()
  195. //      Determine if the specified application is enabled. Return the 
  196. //      result in pbFWAppEnabled. 
  197. //--------------------------------------------------------------------------------------
  198. BOOL FirewallWrapper::IsAppEnabled(
  199.             IN const wchar_t* szFwProcessImageFileName
  200.             )
  201. {
  202.     HRESULT             hr = S_OK;
  203.     BSTR                fwBstrProcessImageFileName = NULL;
  204.     VARIANT_BOOL        vbFwEnabled;
  205.     INetFwAuthorizedApplication*    pFwApp = NULL;
  206.     INetFwAuthorizedApplications*   pFwApps = NULL;
  207.     BOOL bFwAppEnabled = FALSE;
  208.     
  209.     _ASSERT( szFwProcessImageFileName != NULL );
  210.  
  211.     // Retrieve the collection of authorized applications.
  212.     hr = m_pFwProfile->get_AuthorizedApplications( &pFwApps );
  213.     if( FAILED(hr) )
  214.     {
  215.         // printf( "get_AuthorizedApplications failed: 0x%08lx\n", hr );
  216.         goto cleanup;
  217.     }
  218.  
  219.     // Allocate a BSTR for the process image file name.
  220.     fwBstrProcessImageFileName = SysAllocString( szFwProcessImageFileName );
  221.     if( SysStringLen( fwBstrProcessImageFileName ) == 0 )
  222.     {
  223.         hr = E_OUTOFMEMORY;
  224.         // printf( "SysAllocString failed: 0x%08lx\n", hr );
  225.         goto cleanup;
  226.     }
  227.  
  228.     // Attempt to retrieve the authorized application.
  229.     hr = pFwApps->Item( fwBstrProcessImageFileName, &pFwApp );
  230.     if( SUCCEEDED(hr ) )
  231.     {
  232.         // Find out if the authorized application is enabled.
  233.         hr = pFwApp->get_Enabled( &vbFwEnabled );
  234.         if( FAILED(hr) )
  235.         {
  236.             // printf( "get_Enabled failed: 0x%08lx\n", hr );
  237.             goto cleanup;
  238.         }
  239.  
  240.         if( vbFwEnabled != VARIANT_FALSE )
  241.         {
  242.             // The authorized application is enabled.
  243.             bFwAppEnabled = TRUE;
  244.  
  245.             // printf(
  246.             //     "Authorized application %lS is enabled in the firewall.\n",
  247.             //     szFwProcessImageFileName
  248.             //     );
  249.         }
  250.         else
  251.         {
  252.             // printf(
  253.             //     "Authorized application %lS is disabled in the firewall.\n",
  254.             //     szFwProcessImageFileName
  255.             //     );
  256.         }
  257.     }
  258.     else
  259.     {
  260.         // The authorized application was not in the collection.
  261.         hr = S_OK;
  262.  
  263.         // printf(
  264.         //     "Authorized application %lS is disabled in the firewall.\n",
  265.         //     szFwProcessImageFileName
  266.         //     );
  267.     }
  268.  
  269. cleanup:
  270.  
  271.     // Free the BSTR.
  272.     SysFreeString( fwBstrProcessImageFileName );
  273.  
  274.     // Release the authorized application instance.
  275.     if( pFwApp != NULL )
  276.     {
  277.         pFwApp->Release();
  278.     }
  279.  
  280.     // Release the authorized application collection.
  281.     if( pFwApps != NULL )
  282.     {
  283.         pFwApps->Release();
  284.     }
  285.  
  286.     return bFwAppEnabled;
  287. }
  288.  
  289.  
  290.  
  291.  
  292. //--------------------------------------------------------------------------------------
  293. // ExceptionsAllowed()
  294. //      Find out if the system is in no-exceptions mode   
  295. //--------------------------------------------------------------------------------------
  296. BOOL FirewallWrapper::AreExceptionsAllowed()
  297. {
  298.     VARIANT_BOOL        vbNotAllowed = VARIANT_FALSE;
  299.     HRESULT             hr = S_OK;
  300.  
  301.     hr = m_pFwProfile->get_ExceptionsNotAllowed( &vbNotAllowed );
  302.     if( SUCCEEDED(hr) && vbNotAllowed != VARIANT_FALSE )
  303.     {
  304.         return FALSE;
  305.     }
  306.     
  307.     return TRUE; 
  308. }
  309.  
  310.  
  311.  
  312.  
  313. //--------------------------------------------------------------------------------------
  314. // AddAuthorizedApp()
  315. //      Add an application to the exception list (aka AuthorizedApplication list)  
  316. //--------------------------------------------------------------------------------------
  317. HRESULT FirewallWrapper::AddAuthorizedApp(
  318.             IN const wchar_t* szFwProcessImageFileName,
  319.             IN const wchar_t* szFwFriendlyName
  320.             )
  321. {
  322.     HRESULT             hr = S_OK;
  323.     BSTR                fwBstrName = NULL;
  324.     BSTR                fwBstrProcessImageFileName = NULL;
  325.     INetFwAuthorizedApplication*    pFwApp = NULL;
  326.     INetFwAuthorizedApplications*   pFwApps = NULL;
  327.  
  328.     _ASSERT( szFwProcessImageFileName != NULL );
  329.     _ASSERT( szFwFriendlyName != NULL );
  330.  
  331.     // Retrieve the authorized application collection.
  332.     hr = m_pFwProfile->get_AuthorizedApplications( &pFwApps );
  333.     if( FAILED(hr) )
  334.     {
  335.         // printf( "get_AuthorizedApplications failed: 0x%08lx\n", hr );
  336.         goto cleanup;
  337.     }
  338.  
  339.     // Create an instance of an authorized application.
  340.     hr = CoCreateInstance(
  341.             __uuidof(NetFwAuthorizedApplication),
  342.             NULL,
  343.             CLSCTX_INPROC_SERVER,
  344.             __uuidof(INetFwAuthorizedApplication),
  345.             (void**)&pFwApp
  346.             );
  347.     if( FAILED(hr) )
  348.     {
  349.         // printf( "CoCreateInstance failed: 0x%08lx\n", hr );
  350.         goto cleanup;
  351.     }
  352.  
  353.     // Allocate a BSTR for the process image file name.
  354.     fwBstrProcessImageFileName = SysAllocString( szFwProcessImageFileName );
  355.     if( SysStringLen( fwBstrProcessImageFileName ) == 0 )
  356.     {
  357.         hr = E_OUTOFMEMORY;
  358.         // printf( "SysAllocString failed: 0x%08lx\n", hr );
  359.         goto cleanup;
  360.     }
  361.  
  362.     // Set the process image file name.
  363.     hr = pFwApp->put_ProcessImageFileName( fwBstrProcessImageFileName );
  364.     if( FAILED(hr) )
  365.     {
  366.         // printf( "put_ProcessImageFileName failed: 0x%08lx\n", hr );
  367.         goto cleanup;
  368.     }
  369.  
  370.     // Allocate a BSTR for the application friendly name.
  371.     fwBstrName = SysAllocString( szFwFriendlyName );
  372.     if( SysStringLen( fwBstrName ) == 0 )
  373.     {
  374.         hr = E_OUTOFMEMORY;
  375.         // printf( "SysAllocString failed: 0x%08lx\n", hr );
  376.         goto cleanup;
  377.     }
  378.  
  379.     // Set the application friendly name.
  380.     hr = pFwApp->put_Name( fwBstrName );
  381.     if( FAILED(hr) )
  382.     {
  383.         // printf( "put_Name failed: 0x%08lx\n", hr );
  384.         goto cleanup;
  385.     }
  386.  
  387.     // Add the application to the collection.
  388.     hr = pFwApps->Add( pFwApp );
  389.     if( FAILED(hr) )
  390.     {
  391.         // printf( "Add failed: 0x%08lx\n", hr );
  392.         goto cleanup;
  393.     }
  394.  
  395.     // printf(
  396.     //     "Authorized application %lS is now enabled in the firewall.\n",
  397.     //     szFwProcessImageFileName
  398.     //     );
  399.  
  400. cleanup:
  401.  
  402.     // Free the BSTRs.
  403.     SysFreeString( fwBstrName );
  404.     SysFreeString( fwBstrProcessImageFileName );
  405.  
  406.     // Release the authorized application instance.
  407.     if( pFwApp != NULL )
  408.     {
  409.         pFwApp->Release();
  410.     }
  411.  
  412.     // Release the authorized application collection.
  413.     if( pFwApps != NULL )
  414.     {
  415.         pFwApps->Release();
  416.     }
  417.  
  418.     return hr;
  419. }
  420.  
  421.  
  422.  
  423.  
  424. //--------------------------------------------------------------------------------------
  425. // RemoveAuthorizedApp()
  426. //      Remove an application from the exception list (aka AuthorizedApplication list)  
  427. //--------------------------------------------------------------------------------------
  428. HRESULT FirewallWrapper::RemoveAuthorizedApp(
  429.             IN const wchar_t* szFwProcessImageFileName
  430.             )
  431. {
  432.     HRESULT             hr = S_OK;
  433.     BSTR                fwBstrProcessImageFileName = NULL;
  434.     INetFwAuthorizedApplications*   pFwApps = NULL;
  435.  
  436.     _ASSERT( szFwProcessImageFileName != NULL );
  437.  
  438.     // Retrieve the authorized application collection.
  439.     hr = m_pFwProfile->get_AuthorizedApplications( &pFwApps );
  440.     if( FAILED(hr) )
  441.     {
  442.         // printf( "get_AuthorizedApplications failed: 0x%08lx\n", hr );
  443.         goto cleanup;
  444.     }
  445.  
  446.     // Allocate a BSTR for the process image file name.
  447.     fwBstrProcessImageFileName = SysAllocString( szFwProcessImageFileName );
  448.     if( SysStringLen( fwBstrProcessImageFileName ) == 0 )
  449.     {
  450.         hr = E_OUTOFMEMORY;
  451.         // printf( "SysAllocString failed: 0x%08lx\n", hr );
  452.         goto cleanup;
  453.     }
  454.  
  455.  
  456.     // Remove the application from the collection.
  457.     hr = pFwApps->Remove( fwBstrProcessImageFileName );
  458.     if( FAILED(hr) )
  459.     {
  460.         // printf( "Remove failed: 0x%08lx\n", hr );
  461.         goto cleanup;
  462.     }
  463.  
  464.     // printf(
  465.     //     "Authorized application %lS is now removed from the firewall.\n",
  466.     //     szFwProcessImageFileName
  467.     //     );
  468.  
  469. cleanup:
  470.  
  471.     // Free the BSTRs.
  472.     SysFreeString( fwBstrProcessImageFileName );
  473.  
  474.     // Release the authorized application collection.
  475.     if( pFwApps != NULL )
  476.     {
  477.         pFwApps->Release();
  478.     }
  479.  
  480.     return hr;
  481. }
  482.  
  483.  
  484.  
  485.  
  486. //--------------------------------------------------------------------------------------
  487. // OnInstallApplication() 
  488. // Add the application to the exception (aka authorized) list.
  489. // Returns true if we've been added.
  490. //--------------------------------------------------------------------------------------
  491. BOOL OnInstallApplication(
  492.             IN const wchar_t* szFwProcessImageFileName,
  493.             IN const wchar_t* szFwFriendlyName
  494.             )
  495. {
  496.     FirewallWrapper* pfw = FirewallWrapper::Create();
  497.     if( !pfw )
  498.         return FALSE; 
  499.  
  500.     HRESULT hr = pfw->AddAuthorizedApp(            
  501.         szFwProcessImageFileName,
  502.         szFwFriendlyName
  503.         );
  504.     return SUCCEEDED(hr);
  505. }
  506.  
  507.  
  508.  
  509.  
  510. //--------------------------------------------------------------------------------------
  511. // OnUninstallApplication()
  512. //      Remove the application from the exception list.
  513. //--------------------------------------------------------------------------------------
  514. BOOL OnUninstallApplication(
  515.             IN const wchar_t* szFwProcessImageFileName
  516.             )
  517. {
  518.     FirewallWrapper* pfw = FirewallWrapper::Create();
  519.     if( !pfw )
  520.         return FALSE; 
  521.     
  522.     HRESULT hr = pfw->RemoveAuthorizedApp( 
  523.         szFwProcessImageFileName
  524.         );
  525.     return SUCCEEDED(hr);
  526. }
  527.  
  528.  
  529.  
  530.  
  531. //--------------------------------------------------------------------------------------
  532. // CanHostMultiplayer() 
  533. //      Check that the firewall is properly configured for the game. 
  534. //      Returns FALSE if the firewall is configured to block us from hosting. 
  535. //--------------------------------------------------------------------------------------
  536. BOOL CanHostMultiplayer(
  537.             IN const wchar_t* szFwProcessImageFileName
  538.             )
  539. {
  540.     FirewallWrapper* pfw = FirewallWrapper::Create();
  541.     if( !pfw )
  542.         return TRUE; 
  543.     
  544.     if( !pfw->IsAppEnabled(szFwProcessImageFileName) )
  545.     {
  546.         printf( "Application is not enabled in the firewall. You will not be able host games or join a peer-to-peer game. Depending on the game, you may be able to join.\n" );
  547.         return FALSE;
  548.     }
  549.  
  550.     if( !pfw->AreExceptionsAllowed() )
  551.     {
  552.         printf( "Firewall is on with no exceptions. You will not be able host games or join a peer-to-peer game. Depending on the game, you may be able to join.\n" );
  553.         return FALSE;
  554.     }
  555.  
  556.     return TRUE; 
  557. }
  558.  
  559.  
  560.  
  561.  
  562. //--------------------------------------------------------------------------------------
  563. // wmain()
  564. // Run the two basic scenarios:
  565. //          When installing, add the game to the firewall 
  566. //          When launching multiplayer, check firewall settings 
  567. //--------------------------------------------------------------------------------------
  568. int __cdecl main( int argc, wchar_t* argv[] )
  569. {
  570.  
  571.     HRESULT hrComInit = CoInitializeEx(
  572.                  0,
  573.                  COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE
  574.                  );
  575.     if( hrComInit != RPC_E_CHANGED_MODE && FAILED(hrComInit) )
  576.     {
  577.         printf( "Failed to init COM: 0x%08lx\n", hrComInit );
  578.         return 0; 
  579.     }
  580.  
  581.     //--------------------------------------------------------------------------------------
  582.     // First scenario:  During the install process
  583.     // Add the game executable to the exception (aka authorized) list.
  584.     // Note not to add "setup.exe" to the exception list, instead add main game executable.
  585.     //--------------------------------------------------------------------------------------
  586.     WCHAR strGameExeFullPath[MAX_PATH];  
  587.  
  588.     // TODO: change this and make sure this isn't strGameExeFullPath isn't "setup.exe"
  589.     // but instead your main game executable
  590.     GetModuleFileName( NULL, strGameExeFullPath, MAX_PATH ); 
  591.  
  592.     printf( "First scenario during install process:\n" );
  593.     printf( "Add the application to the exception (aka authorized) list.\n" );
  594.     printf( "Note: change the source in this sample to match your game executable name.\n" );
  595.  
  596.     WCHAR* strFriendlyAppName = L"Firewall Sample";  // TODO: Change this 
  597.     BOOL bSuccess = OnInstallApplication( strGameExeFullPath, strFriendlyAppName );
  598.     if( !bSuccess )
  599.     {
  600.         printf( "Could not add app to the exception list. "
  601.                 "If we're running on an OS older than XPSP2 this is normal.\n" );
  602.     }
  603.     else
  604.     {
  605.         printf( "Success!\n" );
  606.     }
  607.  
  608.     //--------------------------------------------------------------------------------------
  609.     // Second scenario:  When we launch multiplayer
  610.     // Check firewall state to ensure the app is still ready to go 
  611.     //--------------------------------------------------------------------------------------
  612.     printf( "\nSecond scenario when launching multiplayer:\n" );
  613.     printf( "Check firewall state to ensure the app is still ready to go.\n" );
  614.     if( CanHostMultiplayer( strGameExeFullPath ) )
  615.     {
  616.         printf( "Success!\n" );
  617.     }
  618.     else
  619.     {
  620.         printf( "Failed!\n" );
  621.     }
  622.  
  623.  
  624.     //--------------------------------------------------------------------------------------
  625.     // Last scenario: During the Uninstall process
  626.     // Remove the application from the exception list.
  627.     //--------------------------------------------------------------------------------------
  628.     printf( "\nLast scenario during uninstall process:\n" );
  629.     printf( "Remove the application from the exception list.\n" );
  630.     bSuccess = OnUninstallApplication( strGameExeFullPath );
  631.     if( !bSuccess )
  632.     {
  633.         printf( "Failed to remove app from to the exception list. \n" );
  634.     }
  635.     else
  636.     {
  637.         printf( "Success!\n" );
  638.     }
  639.  
  640.     // Uninitialize COM.
  641.     if( SUCCEEDED(hrComInit) )
  642.     {
  643.         CoUninitialize();
  644.     }
  645.  
  646.     printf( "\nPress a key to exit\n" );
  647.     _getch();
  648.  
  649.     return 0;
  650. }
  651.  
  652.